﻿#include "ClientSession.hpp"

ClientSession::ClientSession(boost::asio::io_service& ioservice):_socket(ioservice),_authLogin(false),_readFlag(1)
{
  memset(_data,'\0',sizeof(_data));
}

ClientSession::~ClientSession()
{

}

void ClientSession::start()
{
    login();        	
}

void ClientSession::handle_write(const boost::system::error_code& error)
{
    if(error)
    {
       _socket.close();
       return;
    }
}

void ClientSession::login()
{
	  string lastReadLoginName;
	  boost::asio::async_write(_socket, boost::asio::buffer("please enter userName:"),
    	           boost::bind(&ClientSession::handle_write, shared_from_this(), boost::asio::placeholders::error));
    	           	
    _socket.async_read_some(boost::asio::buffer(_data, 1024),
                boost::bind(&ClientSession::processLogin,shared_from_this(),
                  boost::asio::placeholders::error, lastReadLoginName));
}

void ClientSession::processLogin(const boost::system::error_code& error, const string& lastReadLoginName)
{
	  if(error)
    {
       _socket.close();
       return;
    }
    string loginName(_data);
    loginName = lastReadLoginName+loginName;
    cout << "read from client:"<< loginName << endl;
    if(loginName[loginName.size()-1] != '\n'){
    	 //还没有读取完整，继续读取
    	 _readFlag = 0;
    	 _socket.async_read_some(boost::asio::buffer(_data, 1024),
                boost::bind(&ClientSession::processLogin, shared_from_this(),boost::asio::placeholders::error, loginName));
    }else{
      _readFlag = 1;
      memset(_data,'\0',sizeof(_data));
      
      loginName = loginName.substr(0, loginName.length()-2);
    
      boost::asio::async_write(_socket, boost::asio::buffer("\nplease enter password:"),
    	           boost::bind(&ClientSession::handle_write, shared_from_this(), boost::asio::placeholders::error));
    	
    	string lastReadPwd;           	
      _socket.async_read_some(boost::asio::buffer(_data, 1024),
                boost::bind(&ClientSession::authLogin, shared_from_this(),boost::asio::placeholders::error, loginName, lastReadPwd));
    }
}

void ClientSession::authLogin(const boost::system::error_code& error, const string& loginName, const string& lastReadPwd)
{
	 if(error)
   {
       cout << "authLogin err:" << error <<endl;
       _socket.close();
       return;
   }
   
   cout << "loginName:" << loginName << ",length:"<< loginName.length() << endl;
   if(loginName == "admin"){
   	   cout << "loginName is admin." << endl;
       string password(_data);
       password = lastReadPwd + password;
       cout << "read from client password:"<< password << endl;
       if(password[password.size()-1] != '\n'){
       	  //还没有读取完整，继续读取
    	   _readFlag = 0;
    	   _socket.async_read_some(boost::asio::buffer(_data, 1024),
                boost::bind(&ClientSession::authLogin, shared_from_this(),boost::asio::placeholders::error, loginName, password));
       }else{
       	 _readFlag = 1;
       	 password = password.substr(0, password.length()-2);
	       if(password != "123"){
	       	  cout << loginName << " password error." << endl;
	       	  boost::asio::async_write(_socket, boost::asio::buffer("auth error!"),
	    	           boost::bind(&ClientSession::handle_write, shared_from_this(), boost::asio::placeholders::error));
	    	    login();
	       }else{
	       	  cout << loginName << " login success!\n";
	       	  _authLogin = true;
	       	  boost::asio::async_write(_socket, boost::asio::buffer("220. login success"),
	    	           boost::bind(&ClientSession::handle_write, shared_from_this(), boost::asio::placeholders::error));
	    	    
	    	    _socket.async_read_some(boost::asio::buffer(_data, 1024),
                boost::bind(&ClientSession::cmdProcess, shared_from_this(),boost::asio::placeholders::error));
	       }
      }	
   }else{
   	  cout << loginName << " no user." << endl;
   	  login();
   }	   
}

void ClientSession::cmdProcess(const boost::system::error_code& error)
{
	 if(!_authLogin){
	 	  login();
	 }else{
	 	  char cmd[5];
	 	  strncpy(cmd, _data, 4);
	 	  cmd[4] = '\0';
	 	  
	 	  char count[9];
	 	  strncpy(count, _data+4, 8);
	 	  count[8] = '\0';
	 	  int fileLen = atoi(count);
	 	  
	 	  char fname[256];
	 	  strncpy(fname, _data+4+8, 255);
	 	  fname[255] = '\0';
	 	  
	 	  char fdata[1024-4-8-255+1];
	 	  strncpy(fdata, _data+4+8+255, 1024-4-8-255);
	 	  int revlength = strlen(fdata);
	 	  
	 	  std::ofstream fileout;
	 	  fileout.open(fname);
	 	  fileout << fdata;
	 	  
	 	  if(revlength < fileLen){ 
	 	    _socket.async_read_some(boost::asio::buffer(_data, 1024),
                boost::bind(&ClientSession::recevieveFile, shared_from_this(),boost::asio::placeholders::error, revlength, fileLen, fileout));
      }else{
      	fileout.close();
      }
	 }
}

void ClientSession::recevieveFile(const boost::system::error_code& error, int& revlength, int count, ofstream& os)
{
   if(error)
   {
   	 cout << "recevieveFile error:" << error;
   	 return;
   }
   os << _data;	
   revlength += strlen(_data);
   if(revlength < count){
       _socket.async_read_some(boost::asio::buffer(_data, 1024),
                boost::bind(&ClientSession::recevieveFile, shared_from_this(),boost::asio::placeholders::error, revlength, count, os));
   }else{
   	   os.close();
   	   boost::asio::async_write(_socket, boost::asio::buffer("220. recevieveFile success"),
	    	           boost::bind(&ClientSession::handle_write, shared_from_this(), boost::asio::placeholders::error));
   }
}

void ClientSession::handle_read(const boost::system::error_code& error)
{
    
    if(!error)
    {
        std::cout << _data << std::endl;
        //boost::asio::async_read(m_socket,boost::asio::buffer(data_,max_len),

        //    boost::bind(&clientSession::handle_read,shared_from_this(),

        //    boost::asio::placeholders::error));

        _socket.async_read_some(boost::asio::buffer(_data, 1024),
            boost::bind(&ClientSession::handle_read,shared_from_this(),
              boost::asio::placeholders::error));
    }
    else
    {
        _socket.close();
    }
}